package com.inspur.edp.formserver.vmmanager.createvmmetadata;


import com.inspur.edp.bef.bizentity.operation.componentbase.BizParameter;
import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.bef.component.base.VoidReturnType;
import com.inspur.edp.bef.component.detailcmpentity.vm.VMComponent;
import com.inspur.edp.bef.component.detailcmpentity.vm.VMMethodParameter;
import com.inspur.edp.bef.component.enums.ParameterCollectionType;
import com.inspur.edp.bef.component.enums.ParameterMode;
import com.inspur.edp.bef.component.enums.ParameterType;
import com.inspur.edp.formserver.viewmodel.action.IViewModelParameter;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelParameter;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelVoidReturnValue;
import com.inspur.edp.formserver.viewmodel.common.VMCollectionParameterType;
import com.inspur.edp.formserver.viewmodel.common.VMParameterMode;
import com.inspur.edp.formserver.viewmodel.common.VMParameterType;
import com.inspur.edp.formserver.viewmodel.util.ViewModelUtils;
import com.inspur.edp.formserver.vmmanager.generatacmpcode.JavaCompCodeNames;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.itextpdf.text.Meta;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public class MappedCdpActionComponentGenerator
{
	/**
	 业务实体编号

	*/
	protected String vmActionCode;
	/**
	 业务实体程序集名称

	*/
	protected String assemblyName;

	protected String namespace;
	/**
	 业务对象ID

	*/
	protected String bizObjectID;
	/**
	 原始构件

	*/
	protected VMComponent originalComponent;

	 public static MappedCdpActionComponentGenerator getInstance(){
	 	return new MappedCdpActionComponentGenerator();
	 }
	private MappedCdpActionComponentGenerator()
	{
	}

	/**
	 生成构件元数据

	 @param mappedCdpAction 业务操作
	 @param path 生成指定路径
	 @param vmActionCode 业务实体编号
	 @param assemblyName 业务实体程序集名称
	 @param bizObjectID 业务对象ID
	*/
	public final String GenerateComponent(MappedCdpAction mappedCdpAction, String path, String vmActionCode, String assemblyName, String defaltnamespace, String bizObjectID)
	{
		this.vmActionCode = vmActionCode;
		this.assemblyName = assemblyName;
		namespace = defaltnamespace;
		this.bizObjectID = bizObjectID;
		if (ViewModelUtils.checkNull(mappedCdpAction.getComponentEntityId()))
		{
			createComponent(mappedCdpAction, path);
			return mappedCdpAction.getCode();
		}
		else
		{
			modifyComponent(mappedCdpAction, path);
		}
		return null;
	}
	/**
	 新建构件

	 @param action
	 @param path
	*/
	private void createComponent(MappedCdpAction action, String path)
	{
		//1、构建实体
		VMComponent component = new VMComponent();
		this.originalComponent = null;
		//2、赋值
		evaluateComponentInfo(component, action,true);
		//3、生成构件
		String componentMetadataName = establishComponent(component, path);
		//4、建立Action与元数据之间的关联关系
		action.setComponentEntityId(component.getComponentID());
		//操作的ComponentName用来记录生成的构件元数据的名称
		action.setComponentName(componentMetadataName);
	}

	///#region 构件赋值 isInit默认为true
	private void evaluateComponentInfo(VMComponent component, MappedCdpAction action, boolean isInit)
	{
		//1、基本信息
		evaluateComponentBasicInfo(component, action, isInit);
		//2、参数信息
		evaluateComponentParameterInfos(component, action);
		//3、返回值信息
		evaluateComponentReturnValueInfo(component, action);
	}
	private void evaluateComponentBasicInfo(VMComponent component, MappedCdpAction action, boolean isInit)
	{
		if (!ViewModelUtils.checkNull(action.getComponentEntityId()))
		{
			component.setComponentID(action.getComponentEntityId());
		}
		component.setComponentCode(action.getCode());
		component.setComponentName(action.getName());
		component.setComponentDescription("");  //无描述信息
		component.getVmMethod().setDotnetAssembly(this.assemblyName);

		String suffix = String.format("%1$s%2$s%3$s%4$s",'.',this.vmActionCode, '.', JavaCompCodeNames.VOActionNameSpaceSuffix);
		String packageName = javaModuleImportPackage(namespace);
		packageName = String.format("%1$s%2$s",packageName, suffix.toLowerCase());

		if (this.originalComponent != null)
		{
			component.getVmMethod().setDotnetClassName(originalComponent.getMethod().getDotnetClassName()); 
			component.getMethod().setClassName(javaModuleClassName(originalComponent.getMethod().getDotnetClassName(),packageName)); 
		}
		else
		{
			//20190507wj_新生成的构件，VM=>VO
			if (isInit)
			{
				component.getVmMethod().setDotnetClassName((String.format("%1$s.%2$s.%3$s%4$s", this.namespace, JavaCompCodeNames.VMActionNameSpaceSuffix, action.getCode(), JavaCompCodeNames.VMActionClassNameSuffix)));
				component.getMethod().setClassName(javaModuleClassName(component.getVmMethod().getDotnetClassName(), packageName));
			}
		}
	}

	protected final String javaModuleClassName(String classNamestr, String packageNameStr)
	{
		String connections = "";
		if (!ViewModelUtils.checkNull(classNamestr))
		{
			connections = classNamestr.substring(classNamestr.lastIndexOf('.'));
			connections = String.format("%1$s%2$s",packageNameStr, connections);
		}

		return (connections);
	}

	protected final String javaModuleImportPackage(String packageName)
	{
		String[] strArray = packageName.split("[.]", -1);
		String str = "com.";
		int i;

		for (i = 0; i < strArray.length - 1; i++)
		{
			str += strArray[i].toLowerCase() + ".";
		}
		return (str + strArray[i].toLowerCase());
	}
	private void evaluateComponentParameterInfos(VMComponent component, MappedCdpAction action)
	{
		for (Object parameter : action.getParameterCollection())
		{
			evaluateComponentParameterInfo((IViewModelParameter) parameter, component);
		}
	}
	private void evaluateComponentParameterInfo(IViewModelParameter vmParameter, VMComponent component)
	{
		VMMethodParameter tempVar = new VMMethodParameter();
		tempVar.setID(vmParameter.getID());
		tempVar.setParamCode(vmParameter.getParamCode());
		tempVar.setParamName( vmParameter.getParamName());
		tempVar.setParamDescription(vmParameter.getParamDescription());
		tempVar.setMode(ParameterMode.valueOf(vmParameter.getMode().name().toString()));
		tempVar.setParameterType(ParameterType.valueOf(vmParameter.getParameterType().name().toString()));
		tempVar.setAssembly(vmParameter.getAssembly());
		tempVar.setDotnetClassName(((ViewModelParameter)vmParameter).getDotnetClassName());
		tempVar.setClassName(vmParameter.getClassName());
		tempVar.setParameterCollectionType(ParameterCollectionType.valueOf(vmParameter.getCollectionParameterType().name().toString()));
		VMMethodParameter parameter = tempVar;

		component.getVmMethod().getParams().add(parameter);
	}
	private void evaluateComponentReturnValueInfo(VMComponent component, MappedCdpAction action)
	{
		//类型
		if (action.getReturnValue() instanceof ViewModelVoidReturnValue)
		{
			component.getVmMethod().setReturnValue(new VoidReturnType());
		}
		else
		{
			component.getVmMethod().getReturnValue().setParameterCollectionType(ParameterCollectionType.valueOf(action.getReturnValue().getCollectionParameterType().name().toString()));
			component.getVmMethod().getReturnValue().setParameterType(ParameterType.valueOf(action.getReturnValue().getParameterType().name().toString()));
			component.getVmMethod().getReturnValue().setAssembly(action.getReturnValue().getAssembly());
			component.getVmMethod().getReturnValue().setDotnetClassName(action.getReturnValue().getDotnetClassName());
			component.getVmMethod().getReturnValue().setClassName(action.getReturnValue().getClassName());
		}
		//基本信息
		component.getVmMethod().getReturnValue().setID(action.getReturnValue().getID());
		component.getVmMethod().getReturnValue().setParamDescription(action.getReturnValue().getParamDescription());
	}
		///#endregion

	/**
	 生成构件实体对应的构件元数据

	 @param component 构件实体
	 @param path 生成构件元数据指定路径
	 @return
	 生成的构件元数据名称
	 <see cref="string"/>

	*/
	private String establishComponent(GspComponent component, String path)
	{
		return GspMetadataExchangeUtil.getInstance().establishVMMetdadata(component, path, this.vmActionCode, this.bizObjectID, this.namespace);
	}

	/**
	 修改构件

	 @param action
	 @param path
	*/
	private void modifyComponent(MappedCdpAction action, String path)
	{
		//1、构建实体
		VMComponent component = new VMComponent();

		//3、获取要修改的构件元数据完整路径（包括后缀）
		String fullPath = "";
		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
		// 带针对不同类型构件的扩展名的文件全名
		String metadataFileNameWithExtendName = action.getComponentName() + ".vmCmp";
		if (!metadataService.isMetadataExist(path, metadataFileNameWithExtendName))
		{
			throw new RuntimeException("构件元数据" + metadataFileNameWithExtendName + "不存在！");
		}
		fullPath = path + ViewModelUtils.getSeparator() + action.getComponentName() + ".vmCmp";
		this.originalComponent = getoriginalComponent(path, metadataFileNameWithExtendName);
		//2、赋值
		evaluateComponentInfo(component, action,true);
		//4、修改更新构件元数据
		GspMetadataExchangeUtil.getInstance().updateGspMetadata(component, fullPath, this.vmActionCode, this.bizObjectID, this.namespace);
	}
	private VMComponent getoriginalComponent(String path, String metadataFileNameWithSuffix)
	{
		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
		GspMetadata metadata = metadataService.loadMetadata(metadataFileNameWithSuffix, path);
		VMComponent originalComponent = (VMComponent)((metadata.getContent() instanceof VMComponent) ? metadata.getContent() : null);
		return originalComponent;
	}
}